import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import type { AppDispatch } from '@/types/store'
import { Channel, Article } from '@/types/data'
import DataServe from '@/api/home'
import { getChannels, hasToken, setChannels } from '@/utils/storage'
import { differenceBy } from 'lodash'
import store from '@/store/index'

const homeSlice = createSlice({
  name: 'home',
  initialState: {
    channels: [] as Array<Channel>,
    recommendChannels: [] as Array<Channel>,
    activeChannel: 0,
    channelArticles: {} as { [key: number]: { pre_timestamp: number; results: Array<Article> } }
  },
  reducers: {
    setUserChannel(state, action: PayloadAction<Array<Channel>>) {
      state.channels = action.payload
    },
    setRecommendChannels(state, action: PayloadAction<Array<Channel>>) {
      //1， 使用es6方法
      // state.recommendChannels = action.payload.filter((item) => {
      //   return !state.channels.find((v) => v.id === item.id)
      // })
      //2， 使用loadsh,differenceBy，第一个参数为全量数据，第二个参数为已有数据，第三个参数为对比的key值，返回剩余数据
      state.recommendChannels = differenceBy(action.payload, state.channels, 'id')
    },
    setActiveChannel(state, action: PayloadAction<number>) {
      state.activeChannel = action.payload
    },
    setChannelArticles(
      state,
      action: PayloadAction<{
        timestamp: number
        channel_id: number
        results: Array<Article>
        actionType: 'push' | 'reset'
      }>
    ) {
      const {
        payload: { channel_id, timestamp, results, actionType }
      } = action
      if (actionType === 'push') {
        const oldResult = state.channelArticles[channel_id]?.results || []
        state.channelArticles[channel_id] = {
          pre_timestamp: timestamp,
          results: [...oldResult, ...results]
        }
      } else if (actionType === 'reset') {
        state.channelArticles[channel_id] = {
          pre_timestamp: timestamp,
          results: results
        }
      }
    }
  }
})

export const { setUserChannel, setRecommendChannels, setActiveChannel, setChannelArticles } =
  homeSlice.actions

// 获取用户频道列表
export function getUserChannel() {
  return async (dispatch: AppDispatch) => {
    if (hasToken()) {
      // 登录了,请求获取频道
      const {
        data: { channels }
      } = await DataServe.getUserChannel()
      dispatch(setUserChannel(channels))
    } else {
      // 未登录，本地获取频道
      const channels = getChannels()
      if (channels.length > 0) {
        // 本地有缓存频道
        dispatch(setUserChannel(channels))
      } else {
        // 本地无缓存频道
        // 请求频道信息
        // 因为未登录，会跳转登录页，登录完成后会重定向，再次发起获取频道请求，
        const {
          data: { channels: remoteChannels }
        } = await DataServe.getUserChannel()
        dispatch(setUserChannel(remoteChannels))
        // 请求获取的频道进行本地缓存
        setChannels(remoteChannels)
      }
    }
  }
}

//获取所有频道数据
export function getRecommendChannels() {
  return async (dispatch: AppDispatch) => {
    const {
      data: { channels }
    } = await DataServe.getAllChannel()
    dispatch(setRecommendChannels(channels))
  }
}

// 删除频道
export function delChannel(payload: number) {
  return async (dispatch: AppDispatch) => {
    // 1，先获取原频道
    const {
      homeSlice: { channels }
    } = store.getState()
    // 2,过滤出新频道列表
    const newChannels = channels.filter((item) => item.id !== payload)
    // 3，判断有无登录
    if (hasToken()) {
      // 4-1，登录了,发送请求更新服务器上用户频道列表
      await DataServe.updateUserChannels({ channels: newChannels })
    } else {
      // 4-2,没有登录,仅更新到本地存储
      setChannels(newChannels)
    }
    // 5，更新redux中频道列表
    dispatch(setUserChannel(newChannels))
  }
}

// 获取对应频道文章列表
export function getArticleListAsync(
  payload: { channel_id: number; timestamp: number },
  actionType: 'push' | 'reset'
) {
  return async (dispatch: AppDispatch) => {
    const {
      data: { pre_timestamp, results }
    } = await DataServe.getArticleList(payload)
    dispatch(
      setChannelArticles({
        timestamp: +pre_timestamp,
        channel_id: payload.channel_id,
        results: results,
        actionType
      })
    )
  }
}

export default homeSlice.reducer
